package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import cn.hutool.json.JSONUtil;
import com.zzyl.dto.LoginDto;
import com.zzyl.entity.User;
import com.zzyl.enums.BasicEnum;
import com.zzyl.exception.BaseException;
import com.zzyl.properties.JwtProperties;
import com.zzyl.service.LoginService;
import com.zzyl.service.ResourceService;
import com.zzyl.service.UserService;
import com.zzyl.utils.JwtUtil;
import com.zzyl.vo.UserVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserService userService;
    @Autowired
    private JwtProperties jwtProp;
    @Autowired
    private ResourceService resourceService;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public UserVo login(LoginDto dto) {
//        根据用户名查询用户
        User user = userService.findUserByUserName(dto.getUsername());
//        判断用户是否存在
        if (user == null){
            log.error("用户不存在,登录失败!");
            throw new BaseException(BasicEnum.USER_EMPTY_EXCEPTION);
        }
//        判断用户账号是否被禁用
        if ("1".equals(user.getDataState())){
            log.error("用户账号被禁用,登录失败!");
            throw new BaseException(BasicEnum.USER_EMPTY_EXCEPTION);
        }
//        判断密码是否正确,Bcrypt加密
        boolean b = BCrypt.checkpw(dto.getPassword(), user.getPassword());
        if (!b){
            log.error("密码错误,登录失败!");
            throw new BaseException(BasicEnum.ORIGINAL_PASSWORD_ERROR);
        }
//        对象转换属性拷贝
        UserVo vo = BeanUtil.toBean(user, UserVo.class);
//        密码脱敏
        vo.setPassword("");
//        根据用户生成jwt
        Map<String, Object> claims = new HashMap<>();
//        放入token的用户数据
        claims.put("currentUser", JSONUtil.toJsonStr(vo));
        String token = JwtUtil.createJWT(jwtProp.getBase64EncodedSecretKey(), jwtProp.getTtl(), claims);
//        把jwt放入userVo中
        vo.setUserToken(token);
//        查询用户可以操作的 按钮资源信息
        Long userId = vo.getId();
        List<String> urls = resourceService.findButResourceByUserId(userId);
//        存储到Redis中  使用string  key: userid  value: urls
        redisTemplate.opsForValue().set("user:access:url:" + userId,JSONUtil.toJsonStr(urls));
//        返回token
        return vo;
    }
}